import { BadRequestException, Injectable } from '@nestjs/common';
import { CreateAdventureDto } from './dto/create-adventure.dto';
import { UpdateAdventureDto } from './dto/update-adventure.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Adventure } from './entities/adventure.entity';
import { Between, FindOptionsWhere, Like, Repository } from 'typeorm';
import { User } from '../user/entities/user.entity';
import { IPaginationOptions, paginate } from 'nestjs-typeorm-paginate';
import { adventureQueryVo } from '@/common/interface';
import { UserService } from '../user/user.service';
@Injectable()
export class AdventureService {
  fields: string[];
  constructor(
    @InjectRepository(Adventure)
    private readonly adventureRepository: Repository<Adventure>,
    private readonly userService: UserService
  ) {
    this.fields = ['name', 'desc', 'level', 'title', 'tasks', 'members'];
  }

  findOneByName(name: string) {
    return this.adventureRepository.findOne({
      where: { name }
    });
  }

  async create(createAdventureDto: CreateAdventureDto) {
    // 重名检验
    const hasAdventure = await this.findOneByName(createAdventureDto.name);
    if (hasAdventure) {
      throw new BadRequestException({
        code: 400,
        message: '工会已经存在'
      });
    }
    // 实体实例化
    const adventure = new Adventure();
    const fields = [...new Set(this.fields)];
    fields.forEach((v) => {
      adventure[v] = createAdventureDto[v];
    });

    // 关联用户
    if (createAdventureDto?.members?.length > 0) {
      const members = createAdventureDto.members.map((item) => {
        const member = new User();
        member.id = item.id;
        return member;
      });
      adventure.members = members;
    }

    return this.adventureRepository.save(adventure);
  }

  findAll(options: IPaginationOptions, adventureQuery: adventureQueryVo) {
    const { name, queryDate } = adventureQuery;
    const where: FindOptionsWhere<Adventure> = {};
    if (name) {
      where.name = Like(`%${name}%`);
    }
    if (queryDate?.length > 0) {
      where.createdAt = Between(queryDate[0], queryDate[1]);
    }

    return paginate(this.adventureRepository, options, { where });
  }

  findOne(id: number) {
    return this.adventureRepository.findOne({
      where: { id }
    });
  }

  async update(updateAdventureDto: UpdateAdventureDto) {
    const adventure = new Adventure();
    const fields = [...new Set(this.fields), 'id'];
    fields.forEach((v) => {
      adventure[v] = updateAdventureDto[v];
    });

    // 关联用户
    if (updateAdventureDto?.members?.length > 0) {
      const members = updateAdventureDto.members.map((item) => {
        const member = new User();
        member.id = item.id;
        return member;
      });
      adventure.members = members;
    }

    return this.adventureRepository.save(adventure);
  }

  async remove(id: number) {
    const adventure = await this.findOne(id);
    if (adventure?.members?.length > 0) {
      adventure.members.map(async (item) => {
        const user = await this.userService.findOne(item.id);
        // 将user关联的advanture移除
        user.adventure = null;
        // 保存更改
        this.userService.saveUser(user);
      });
    }

    // 删除adventure
    return this.adventureRepository.delete(id);
  }

  async addMember(id: number, members: User[]) {
    const adventure = await this.findOne(id);
    // adventure.members = members.map(({id})=> id)

    return this.adventureRepository.update(id, adventure);
  }
}
